﻿using System;
using System.IO;
using System.Net.Sockets;

namespace ClientAPI.Network
{
    class SendFile
    {
        private string _fileName;
        private string _filePath;
        private string _fileDescription;

        long _tempLengthOfFile;
        long _totalBytesSent;
        long _packetNumber;
        long _packetSize;

        int _bufferSize;

        private bool _fileIncomplete = true;
        private bool _reSend = false;

        FileInfo _fileInfo;
        private Socket _socket;
        Messenger _messenger;

        public SendFile(string filePath, string fileDescription, Socket socket)
        {
            string[] tempArray = filePath.Split('\\');
            _fileName = tempArray[tempArray.Length - 1];
            System.Diagnostics.Debug.WriteLine(_fileName);
            _filePath = filePath;
            _fileDescription = fileDescription;
            _socket = socket;
            _messenger = new Messenger(_socket, "FILE SEND ");
            _fileInfo = new FileInfo(_filePath);
            _bufferSize = Settings.Instance.GetBufferSize();
            _tempLengthOfFile = _fileInfo.Length;
            _packetNumber = 1;
        }

        public void Send()
        {
            _messenger.SendMessage("$FRANK¶FILE¶UPLOAD¶" + _fileName + "¶" + _fileDescription + "¶" + CommandProtocol.Instance.GetUserName() + "¶");

            FileStream fileData = new FileStream(_filePath, FileMode.Open, FileAccess.Read);

            _totalBytesSent = 0;

            //System.Diagnostics.Debug.WriteLine("waiting for received details ok");
            while (WaitForResponce()) { }

            _messenger.SendMessage("$FRANK¶FILE¶UPLOAD¶" + Math.Ceiling((double)_fileInfo.Length / Settings.Instance.GetBufferSize()) + "¶");

            while (WaitForResponce()) { }

            _reSend = false;

            while (_fileIncomplete)
            {
                GetPacketSize();

                byte[] buffer = new byte[_packetSize];
                if (!_reSend) fileData.Read(buffer, 0, (int)_packetSize);

                _messenger.SendMessage("$FRANK¶FILE¶UPLOAD¶" + _packetNumber + "¶" + _packetSize + "¶");

                while (WaitForResponce()) { }

                //System.Diagnostics.Debug.WriteLine("Sending Bytes");
                _socket.Send(buffer);

                while (WaitForResponce()) { }

                if (!_reSend) _packetNumber++;
            }

            fileData.Flush();
            fileData.Close();

            _socket.Disconnect(true);
        }

        private bool WaitForResponce()
        {
            string[] message = _messenger.ReceiveFileInformation().Split('¶');

            if (message == null)
            {
                return true;
            }
            else if (message[message.Length - 2] == "OK")
            {
                return false;
            }
            else if (message[message.Length - 2] == "NEXT")
            {
                _reSend = false;
                return false;
            }
            else if (message[message.Length - 2] == "END")
            {
                _fileIncomplete = false;
                return false;
            }
            else if (message[message.Length - 2] == "BAD")
            {
                _reSend = true;
                return false;
            }

            return true;
        }

        private void GetPacketSize()
        {
            if (_tempLengthOfFile % _bufferSize != _tempLengthOfFile)
            {
                _totalBytesSent = _totalBytesSent + _bufferSize;
                _tempLengthOfFile = _tempLengthOfFile - _bufferSize;
                _packetSize = _bufferSize;
            }
            else if (_tempLengthOfFile % _bufferSize == _tempLengthOfFile)
            {
                _totalBytesSent = _totalBytesSent + _tempLengthOfFile;
                _packetSize = _tempLengthOfFile;
            }
        }
    }
}
